from service.PlusterLog import *
from MVC.plstdocument import IDocument
from Tkinter import *
import os
import time
import glob
import re

class Task(PlusterLog):
    """Represent a task."""
    def __init__(self,id,name,view,adapter,doc):
        PlusterLog.__init__(self)
        self.id=id
        self.name=name
        self.start_time=time.ctime()
        self.view=view
        self.adapter=adapter
        self.doc=doc
        #self.log.debug("Create Task Document %d %s"%(id,name))
        #self.log.debug("Task view %s adapter %s doc %s"%(view,adapter,doc))

    def config(self,arg):
        try:
            self.doc.config(arg)
        except:
            self.log.error("Task config() doesn't exist")
    def start (self):
        """ Start a threading task"""
        try:
            self.doc.start()
        except:
            self.log.error("Task is not a threading task")

    def run(self):
        'run method must be implemented in concrete task'
        try:
            self.doc.run()
        except:
            self.log.error("Fatal Error: Task run() doesn't exist ")

    def stop(self):
        try:
            self.doc.stop()
        except:
            self.log.error("Task stop() doesn't exist")

    def stat(self):
        return (self.id,self.name)

class TaskM(PlusterLog,IDocument):
    """Task management class. Responsible for loading task from
    disk configuring it and star, stop it.  """
    manager=None
    def __init__(self,root):
        PlusterLog.__init__(self)
        IDocument.__init__(self)
        self.log.info("Pluster Task Manager start")
        self.next_id=0
        self.task_dict={} #store task object
        self.tkroot=root
        self.task_list=[] #store task name in tasks dir
        self.task_path='./tasks/'
        TaskM.manager=self

    def config (self, task_path):
        """ Config task manager"""
        self.task_path = task_path

    def load_task(self,name):
        """name=string of task name
        load task from disk. Return a task id"""
        self.log.info("Loading Task: %s"%name)
        pkgname="tasks."+name
        try:
            task_pkg=__import__(pkgname)
            task_module=task_pkg.__dict__[name]
            task_class=task_module.__dict__[name+"Task"]
            view_class=task_module.__dict__[name+"View"]
            adapter_class=task_module.__dict__[name+"Adapter"]
        except:
            self.log.debug("Load task error,Check class name")
            raise

        id=self.next_id
        self.next_id+=1
        #This is how this Doc-Adapter-View(aka MVC) work
        #first create instance of doc adapter and view
        #view will call adapter of user's command. adapter will
        #translate it and call doc(aka Module).Doc update itself
        #and use Flush() to call all Views that bind with
        #Doc.Finally, View use Update() to update user interface
        doc=task_class()
        if doc.run:
            #Check if task follow naming convention
            adapter=adapter_class(doc)
            view=view_class(adapter)
            if view.Update:
                doc.AddObserver(view)
                view.show(self.tkroot)
                new_task=Task(id,name,view,adapter,doc)
                self.task_dict[id]=new_task
                #print("add new task to task_dict")
                #print("Load task instance %s success"%name)
                return new_task

        self.log.error('Add new task failed. Can not find run() in Task Class. Read Pluster Task Development Document for more info')


    def run_task(self,id):
        self.task_dict[id].run()

    def config_task(self,id,arg):
        self.task_dict[id].config(arg)

    def remove_task(self,id):
        del(self.task_dict[id])

    def get_task_list(self):
        """Read File name form tasks directory and remove any task
        with initial R/r and base Return a list of tasks name"""
        self.log.debug("Get Task List")
        a=glob.glob(self.task_path+"*.py")
        self.task_list=[]
        a=[os.path.split(m)[1][:-3] for m in a] #get task file name
        #remove all remote tasks start with r or R
        self.task_list=[m for m in a if not m.startswith('r') and \
                            not m.startswith('R')]
        #remove some basic tasks,those tasks do not shown on list
        self.task_list.remove("__init__")
        self.task_list.remove("SSH")
        self.task_list.remove("Info")
        self.task_list.remove("Update")
        return self.task_list





